/*

form.js
*
* this file depends on big-number.js
*
* include the following before including this file:
*
* lib/big-number.js
*
* lib/contrib/jsbn/jsbn.js (needed by big-number.js)
* lib/contrib/jsbn/jsbn2.js (needed by big-number.js)


javascript code for form elements.

Copyright (C) 2009, Chris Allert, All rights reserved.

This program is free software; you can redistribute it and/or modify it under 
the terms of the GNU General Public License as published by the Free Software 
Foundation; either version 3 of the License, or (at your option) any later 
version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY 
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 
PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with 
this program; if not, write to the Free Software Foundation, Inc., 59 Temple 
Place, Suite 330, Boston, MA 02111-1307 USA

The latest version of this file can be downloaded from
http://thought-patches.sourceforge.net/

*/

// these are utility functions for dealing with forms.

function clear_select(s) {
	while (s.options.length > 1) {
		s.remove(1);
	}
	s.options[0].innerHTML = " ";
	s.options[0].value = "_null_";
}

function fill_select(s, a, i) {
	//s: select element
	//a: array of 2-element arrays [val, text]
	//i: selected index
	clear_select(s);
	for (var j = 0; j < a.length; ++j) {
		//select.add doesn't work the same in ie
		s.options[j + 1] = new Option(a[j][1], a[j][0]);
	}
	if (a.length > 0) {
		s.remove(0);
	}
	s.selectedIndex = i;
}

function number_spinner_callback(s) {
	s.number_spinner.do_callback(s.number_spinner);
}

function NumberSpinner (o) {
	// o is options object
	// options are 
	//	select
	//	base
	//	min
	//	max
	//	page_size
	this.select = o.select;
	var me = this;

	if (null == o.base) {
		this.base = new_big_int("10", 10);
	} else {
		this.base = new_big_int("" + o.base, 10);
	}
	if (null != o.min) {
		this.min = new_big_int("" + o.min, 10);
	}
	if (null != o.max) {
		this.max = new_big_int("" + o.max, 10);
	}
	if (null == o.page_size) {
		this.page_size = new_big_int("10", 10);
	} else {
		this.page_size = new_big_int("" + o.page_size, 10);
	}
	if (null == o.value) {
		if (null == this.min) {
			this.value = new_big_int("0", 10);
		} else {
			this.value = this.min.clone();
		}
	} else {
		this.value = new_big_int("" + o.value, 10);
	}

	this.do_callback = function(ns) {
		var s = ns.select;
		var v = s.options[s.selectedIndex].value;
		if ("_gt_" == v) {
			ns.page_gt();
		} else if ("_lt_" == v) {
			ns.page_lt();
		} else {
			ns.change_value(v)
		}
		ns.callback(ns);
	}

	this.page_lt = function () { 
		var i = this.value.subtract(this.value.mod(this.page_size));
		this.change_value("" + i.subtract(BigInteger.ONE));
	};

	this.page_gt = function () { 
		var i = this.value.subtract(this.value.mod(this.page_size));
		this.change_value("" + i.add(this.page_size));
	};

	this.change_base = function(b) {
		this.base = new_big_int("" + b, 10);
		this.update();
	}

	this.change_value = function(v) {
		this.value = new_big_int("" + v, 10);
		this.update();
	}

	this.callback = function (ns) { }

	this.select.number_spinner = me;

	this.add = function(n) {
		this.value.add(new_big_int(n, 10));
	}


	this.update = function() {
		clear_select(this.select);
		var i = this.value.subtract(this.value.mod(this.page_size));
		var last = i.add(this.page_size);
		var seli = 0;
		var a = new Array();

		if (null == this.min || i.compareTo(this.min) > 0) {
			a.push(['_lt_', '-']);
		}

		while (i.compareTo(last) < 0) {
			if (null == this.min || i.compareTo(this.min) >= 0) {
				if (null == this.max || i.compareTo(this.max) <= 0) {
					a.push(["" + i, big_int_format(i, this.base, true)]);
					if (0 == i.compareTo(this.value)) {
						seli = a.length - 1;
					}
				}
			}
			i = i.add(BigInteger.ONE);
		}

		if (null == this.max || last.compareTo(this.max) < 0) {
			a.push(['_gt_', "+"]);
		}

		fill_select(this.select, a, seli);
	}
}

